<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test.js"></script>
</head>
<body>
<script>

description("Ensure correct behavior of createPattern with ImageBitmaps.");
window.jsTestIsAsync = true;

function jsWrapperClass(node)
{
    // returns the ClassName of node
    if (!node)
        return "[null]";
    var string = Object.prototype.toString.apply(node);

    // string will be of the form [object ClassName]
    return string.substr(8, string.length - 9);
}

function shouldBeType(expression, className)
{
    shouldBe("jsWrapperClass(" + expression + ")", "'" + className + "'");
}

function shouldNotBeCalled() {
    testFailed("createImageBitmap promise rejected.");
    finishJSTest();
}

function shouldBeRed(x, y) {
    d = ctx.getImageData(x, y, 1, 1).data;
    shouldBeTrue("d[0] == 255");
    shouldBeTrue("d[1] == 0");
    shouldBeTrue("d[2] == 0");
    shouldBeTrue("d[3] == 255");
}

function shouldBeGreen(x, y) {
    d = ctx.getImageData(x, y, 1, 1).data;
    shouldBeTrue("d[0] == 0");
    shouldBeTrue("d[1] == 255");
    shouldBeTrue("d[2] == 0");
    shouldBeTrue("d[3] == 255");
}

function shouldBeBlue(x, y) {
    d = ctx.getImageData(x, y, 1, 1).data;
    shouldBeTrue("d[0] == 0");
    shouldBeTrue("d[1] == 0");
    shouldBeTrue("d[2] == 255");
    shouldBeTrue("d[3] == 255");
}

function shouldBeBlack(x, y) {
    d = ctx.getImageData(x, y, 1, 1).data;
    shouldBeTrue("d[0] == 0");
    shouldBeTrue("d[1] == 0");
    shouldBeTrue("d[2] == 0");
    shouldBeTrue("d[3] == 255");
}

function shouldBeClear(x, y) {
    // should be transparent black pixels
    d = ctx.getImageData(x, y, 1, 1).data;
    shouldBeTrue("d[0] == 0");
    shouldBeTrue("d[1] == 0");
    shouldBeTrue("d[2] == 0");
    shouldBeTrue("d[3] == 0");
}

var checks = { red: shouldBeRed,
               green: shouldBeGreen,
               blue: shouldBeBlue,
               black: shouldBeBlack,
               clear: shouldBeClear };

function checkQuad(x, y, top_left, top_right, bottom_left, bottom_right) {
    checks[top_left](x, y);
    checks[top_right](x + 1, y);
    checks[bottom_left](x, y + 1);
    checks[bottom_right](x + 1, y + 1);
}

function drawPattern(ctx) {
    // Draw a four-color pattern
    ctx.beginPath();
    ctx.fillStyle = "rgb(255, 0, 0)";
    ctx.fillRect(0, 0, 10, 10);
    ctx.fillStyle = "rgb(0, 255, 0)";
    ctx.fillRect(10, 0, 10, 10);
    ctx.fillStyle = "rgb(0, 0, 255)";
    ctx.fillRect(0, 10, 10, 10);
    ctx.fillStyle = "rgb(0, 0, 0)";
    ctx.fillRect(10, 10, 10, 10);
}

function clearContext(context) {
    context.clearRect(0, 0, 50, 50);
}

var bitmap;
var image;
var testBitmap; // this is an ImageBitmap that is uncropped. We use this to test createImageBitmap(testBitmap)
var d;          // image.imageData
var elements;

var imageWidth = 20;
var imageHeight = 20;

// Draw to an auxiliary canvas.
var aCanvas = document.createElement("canvas");
aCanvas.width = imageWidth;
aCanvas.height = imageHeight;
var aCtx = aCanvas.getContext("2d");
drawPattern(aCtx);

var canvas = document.createElement("canvas");
canvas.setAttribute("width", "50");
canvas.setAttribute("height", "50");
var ctx = canvas.getContext("2d");

image = new Image();
image.onload = imageLoaded;
image.src = aCanvas.toDataURL();

var imageLoaded = false;
var imageBitmapLoaded = false;

function imageLoaded() {
    createImageBitmap(image).then(imageBitmapLoadedCallback, shouldNotBeCalled);
    d = aCtx.getImageData(0, 0, 20, 20);
    imageLoaded = true;
    loaded();
}

function imageBitmapLoadedCallback(imageBitmap) {
    testBitmap = imageBitmap;

    shouldBe("testBitmap.width", "imageWidth");
    shouldBe("testBitmap.height", "imageHeight");

    // width and height are readonly
    testBitmap.width = 42;
    testBitmap.height = 42;
    shouldBe("testBitmap.width", "imageWidth");
    shouldBe("testBitmap.height", "imageHeight");

    imageBitmapLoaded = true;
    loaded();
}

function loaded() {
    if (imageLoaded && imageBitmapLoaded) {
        ctx.fillStyle = ctx.createPattern(testBitmap, "repeat");
        ctx.fillRect(10, 10, 30, 30);

        // Check each pixel quad at each corner.  The filled pattern
        // is 3x3 squares of different colors, so there are four rows
        // of four corners.

        checkQuad(9, 9, "clear", "clear", "clear", "black");
        checkQuad(19, 9, "clear", "clear", "black", "blue");
        checkQuad(29, 9, "clear", "clear", "blue", "black");
        checkQuad(39, 9, "clear", "clear", "black", "clear");

        checkQuad(9, 19, "clear", "black", "clear", "green");
        checkQuad(19, 19, "black", "blue", "green", "red");
        checkQuad(29, 19, "blue", "black", "red", "green");
        checkQuad(39, 19, "black", "clear", "green", "clear");

        checkQuad(9, 29, "clear", "green", "clear", "black");
        checkQuad(19, 29, "green", "red", "black", "blue");
        checkQuad(29, 29, "red", "green", "blue", "black");
        checkQuad(39, 29, "green", "clear", "black", "clear");

        checkQuad(9, 39, "clear", "black", "clear", "clear");
        checkQuad(19, 39, "black", "blue", "clear", "clear");
        checkQuad(29, 39, "blue", "black", "clear", "clear");
        checkQuad(39, 39, "black", "clear", "clear", "clear");

        finishJSTest();
    }
}
</script>
</body>
</html>
